// 首先把要用到的api引入
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router';

// 把涉及到的组件引入
import Film from '../views/Film.vue';
import Mine from '../views/Mine.vue';
import Cinema from '../views/Cinema.vue';
import NotFound from '../views/NotFound.vue';
import Detail from '../views/Detail.vue';
import Login from '../views/Login.vue'

// 当应用规模较大的时候，js包也会变得很大，这会影响到页面加载。很多时候用户进入首页，其实只能看到一部分组件路由，但是我们直接把所有的视图模块都加载进来了，这十分影响性能，所以vue3提供了一个路由懒加载的方式，这里我们演示一下
// 很简单 const/let/var  xxx = ()=>import('/xxx/xxx.vue') 这种格式即可，当然，你甚至可以直接在下面定义路由的component属性里直接通过这样的箭头函数形式赋值，比如本文件中的comingsoon组件就是这样引入的。
const Nowplaying = ()=> import('../views/films/Nowplaying.vue');


// 调用createRotuer()创建一个路由对象，该函数接受一个对象作为参数，对象中要配置好必要信息，比如路由模式和自定义数组
const router = createRouter({
    // history有两种方式，一种是hash模式，一种是history模式，默认是hash模式，也就是路径里会带个#，我们直接调用createWebHashHistory()即可。
    // history: createWebHashHistory(),
    // history模式也很简单，直接引用并调用createWebHistory()即可
    history: createWebHistory(),
    // routes属性是较为关键的，由一个数组构成
    routes: [
        // 每个对象有两个最基本的属性，path代表你自定义的路径，component代表你想让这个路径显示哪个组件的内容，
        // 页面初始化的时候，肯定是没有路径的，所以我们这里利用redirect属性，将地址在页面开始的时候转到/films这里
        {
            path: '/',
            redirect: '/films'
        },
        {
            path: '/login',
            component: Login,
            name: 'login'
        },
        {
            path: '/films',
            component: Film,
            name: 'films',//路由是可以起名字的，专业名称叫做命名路由，意思就是vue组件中通过名字也可以进行路由的转换，不止可以通过路径
            // children表示这个路由还有子路由，比如我们这个案例里，底部导航栏中的电影，他的顶部标签也会有正在热映和即将上映两个模块
            children: [
                {
                    path: '/films/comingsoon',//其实你可以直接 /comingsoon，显示效果也没毛病，但是这样的话可读性就会很差，地址栏只有个comingsoon，无法与films看出来有啥关联
                    component: ()=> import('../views/films/Comingsoon.vue'),//直接在这里懒加载方式引入也是可以的，还能节省代码空间，不用再在最上面写不知道多少行引入了
                    name:'comingsoon'
                },
                {
                    path: '/films/nowplaying',
                    component: Nowplaying,
                    name:'nowplaying'
                },
                // 同样，当用户第一次来到films路径里，我们肯定要默认它跳转到即将上映和正在热映其中一个
                {
                    path: '/films',
                    redirect: '/films/nowplaying',
                }
            ]
        },
        {
            path: '/mine',
            component: Mine,
            name: 'mine',
            // 其实每个路由都可以加一个meta属性，赋值为一个对象，里面包含一些自定义属性名和值。当很多个页面都要权限或者一些个性化操作时，这种方式就显得比较优雅了
            meta:{
                needAuth:true
            }
        },
        {
            path: '/cinema',
            component: Cinema,
            name: 'cinema',
        },
        {
            path: '/detail/:filmId',//:filmId其实就是占位符，未来Detail组件中可以通过route.params.filmId拿到实际路径上的那串数字, 比如路径是/detail/1132，那么filmId就是1132
            component: Detail,
            name: 'detail',
        },
        // 如果你有vue2的路由经验，你肯定知道在最后搞一个 *的路径的路由，去匹配那些错误的路径输入，但是vue3中不允许这么写了
        {
            path: '/:pathMatch(.*)*',//vue3中一般这么去匹配那些未定义的路径，有点复杂，死记也行
            component: NotFound,
            name: 'NotFound'
        }
    ]
});

// 全局拦截，调用beforeEach即可，每次路由跳转之前都要被这个函数拦截下来，然后执行里面这个回调函数。to就是去往哪个路由，from就是从哪个路由来，next就是放行本次拦截的函数。next不执行，路由就不会跳转。next里也可以传入像router.push一样的内容，跳转到指定的路由
router.beforeEach((to, from, next) => {
    // console.log(to,from,next);
    let isAuthenticated = localStorage.getItem('token');
    // 如果要访问 个人中心且未登录，那么就跳转到登录页，这是比较笨的方法。当需要授权的页面多起来，你总不能都像这样写进来吧
    // if (to.path == '/mine' && !isAuthenticated) {
    //     next('/login')
    // }
    // else {
    //     next();
    // }

    // 其实每个路由都可以加一个meta属性，赋值为一个对象，里面包含一些自定义属性名和值。当很多个页面都要权限时，这种方式就显得比较优雅了
    if(to.meta.needAuth && !isAuthenticated){
        next('/login')
    }
    else{
        next();
    }
    document.querySelector('title').innerHTML = to.name;
});

// 除了beforeEach，还有个afterEach，执行在路由跳转之后，也许你会问，跳都跳转完了，这玩意还有啥用啊。别急，这个一般用在收集用户习惯信息的需求里，我们可以在用户每次点击后将一些信息传递给后端，后端可以根据拿到的信息去做一些处理，更方便做一些为您推荐、才您喜欢这类需求
// 注意afterEach的回调函数里是没有next的，因为都跳转完毕了，再搞个next就没有意义了
router.afterEach((to,from)=>{
    console.log('假装给后端传递了一些信息');
    // console.log(to,from);

})

// 然后把你创建好的rotuer对象导出去，注意，到这一步还没完，得在main.js里注册一下
export default router;